﻿using System.Diagnostics;
using System.IO;

namespace USU.MetricsMonitor.Common
{
	/// <summary>
	/// This class is a wrapper of the process standard output stream which takes
	/// care of closing and disposing process resources when appropriate
	/// </summary>
	public class ProcessOutputStream : Stream
	{
		private readonly Process process;

		public ProcessOutputStream(string fileName, string arguments)
			:
				this(Process.Start(new ProcessStartInfo(fileName)
				                   	{
				                   		UseShellExecute = false,
				                   		RedirectStandardInput = true,
				                   		RedirectStandardOutput = true,
										RedirectStandardError = true,
				                   		WindowStyle = ProcessWindowStyle.Hidden,
				                   		CreateNoWindow = true,
				                   		Arguments = arguments,
				                   	})) { }

		public ProcessOutputStream(Process process) { this.process = process; }

        public bool isOK()
        {
            return process.ExitCode == 0;
        }
      
		protected override void Dispose(bool disposing)
		{
			process.Dispose();
			base.Dispose(disposing);
		}

		public override void Close()
		{
			process.Close();
			base.Close();
		}

		public override void Flush() { process.StandardOutput.BaseStream.Flush(); }

		public override long Seek(long offset, SeekOrigin origin)
		{
			return process.StandardOutput.BaseStream.Seek(offset, origin);
		}

		public override void SetLength(long value)
		{
			process.StandardOutput.BaseStream.SetLength(value);
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			var ret = process.StandardOutput.BaseStream.Read(buffer, offset, count);
			return ret;
		}

		public override void Write(byte[] buffer, int offset, int count)
		{
			process.StandardOutput.BaseStream.Write(buffer, offset, count);
		}

		public override bool CanRead
		{
			get { return process.StandardOutput.BaseStream.CanRead; }
		}

		public override bool CanSeek
		{
			get { return process.StandardOutput.BaseStream.CanSeek; }
		}

		public override bool CanWrite
		{
			get { return process.StandardOutput.BaseStream.CanWrite; }
		}

		public override long Length { get { return process.StandardOutput.BaseStream.Length; } }

		public override long Position
		{
			get { return process.StandardOutput.BaseStream.Position; }
			set { process.StandardOutput.BaseStream.Position = value; }
		}
	}
}
